#!/usr/bin/python
# ~*~ coding: utf-8 ~*~

import sys
import json
import os
import importlib
importlib.reload(sys)
from mysqldb import DbSearch
from DingDing import SendMs
import datetime
import time
from tasks import *
#from SelfHealing import SelfHealing
from mailers import SendMessages
from alert_template import AlertTemplate
import redis
from Log import logger,logger_task
#数据库
#获取redis配置
from confs.Configs import *


#alert 队列
redisPool = redis.ConnectionPool(host=redis_host,port=redis_port,db=redis_db,password=redis_password)
client = redis.Redis(connection_pool=redisPool)
#连接redis
rc = redis.Redis(host=redis_host, port=redis_port,db=redis_db,password=redis_password)

content = '如果队列中暂无元素,将休息3秒钟~~~%s %s %s %s '%(redis_host,redis_port,redis_db,redis_password)
#logger.info(redis_host,redis_port,redis_db,redis_password)
logger.info(content)
flag = 'icbc'

#数据库
db = DbSearch()
#alertime 告警次数
#switchtime 从第几次开始执行自愈动作
#maxfixtime 最多执行多少次自愈
maxfixtime = 1
switchtime = 1

#自愈时效性
valid = db.AlertSilence()[3]


while True:
	num = client.llen(flag)
	if num == 0:
		logger.info('sleep 3秒')
		time.sleep(3)

	else:
		comment = '队列中元素个数是%s,开始消费~~~'%(str(num))
		#logger.info(comment)
		task = client.brpop('icbc',1)
		msg = task[1]
		#转换json
		msg = json.loads(msg)

		#判断数据源
		datasource = msg['datasource']
		if datasource == 'prometheus':
			ip = msg['IP']
			action = msg['action']
			tm = msg['tm']
			tma = tm

			#判断时效性
			ntm = datetime.datetime.now()
			tm = datetime.datetime.strptime(tm, '%Y-%m-%d %H:%M:%S')
			if (ntm - tm).seconds > valid * 60:
				logger.info('%s 自愈超过当前时效性,跳过'%ip)
				continue
			# 判断自愈是否在沉默状态和沉默区间
			silence = db.AlertSilence()
			if silence[0] == 'on':
				nowtime = datetime.datetime.now()
				stime = datetime.datetime.now().strftime("%Y-%m-%d ") + silence[1]
				to_stime = datetime.datetime.strptime(stime, '%Y-%m-%d %H:%M:%S')
				etime = datetime.datetime.now().strftime("%Y-%m-%d ") + silence[2]
				to_etime = datetime.datetime.strptime(etime, '%Y-%m-%d %H:%M:%S')
				if to_stime <= nowtime <= to_etime:
					logger.info('prometheus 处于沉默区间,不产生自愈动作')
					continue
				else:
					logger.info('静默功能开启,prometheus准备提交异步自愈...')
					PrometheusDispatch.delay(ip,action,tma)
					logger.info('静默功能开启,prometheus异步自愈提交完毕')
					continue
			else:
				logger.info('静默功能关闭,prometheus触发自愈动作开始...')
				PrometheusDispatch.delay(ip, action, tma)
				continue

		else:
			pass

		#自愈时效性判断
		if 'tm' not in msg:
			continue
		ntm = datetime.datetime.now()
		tm = datetime.datetime.strptime(msg['tm'],'%Y-%m-%d %H:%M:%S')
		if (ntm - tm).seconds > valid*60:
			continue

		#json格式处理
		if '详情' not in msg:
			msg['详情'] = '无'
		for t in AlertTemplate:
			exec("{} = '{}'".format(AlertTemplate[t], msg[t]))

		#IP
		rc.hsetnx(alarm,'IP', ip)

		# alarm 告警项目
		# alertpj 自愈项
		alertpj = 'alertpj'

		if status == 'OK':
			last_status = ''
			if rc.hexists(alarm, alertpj):
				alert = rc.hget(alarm, alertpj)
				alert_loads = json.loads(alert)
				alertime = alert_loads['alertime']
				last_status = alert_loads['status'] if 'status' in alert_loads else ''

			alert_dumps = json.dumps({"alertime":0,"fixtime":0,"status":status})
			rc.hset(alarm,alertpj,alert_dumps)

			#告警信息记录
			if last_status and last_status != status:
				alertmsg = 'IP:%s, 告警项目: %s,自愈项: %s, 告警状态: %s,上次告警状态: %s,告警%d次后恢复,详情: %s' % (ip, alarm, alertpj, status, last_status,alertime,detail)
			else:
				alertmsg = 'IP:%s, 告警项目: %s,自愈项: %s, 告警状态: %s,上次告警状态: %s,详情: %s'%(ip,alarm,alertpj,status,last_status,detail)
			#logger.info(alertmsg)

		else:

			#通过报警项目报警次数去做处理
			if rc.hexists(alarm,alertpj):
				alert = rc.hget(alarm,alertpj)
				alert = json.loads(alert)
				alertime = alert['alertime']
				fixtime = int(alert['fixtime'])
				last_status = alert['status']
				alertime = int(alertime) + 1
				alert['alertime']=alertime
				alert['status'] = status

				##判断告警次数处理逻辑
				#if alertpj in SelfHealing:
				#	switchtime = SelfHealing[alertpj]['time']
				#	print ('switchtime is ',switchtime)
				#else:
				#	continue

				#alertime 告警次数
				#switchtime 从第几次开始执行自愈动作
				#maxfixtime 最多执行多少次自愈

				if alertime >= switchtime:
					if fixtime < maxfixtime:
						ip_list = ip.split(',')
						item_list = recovery.split(',')

						#switch_status = 1
						#for id in item_list:
							#switch_status=1 故障自愈功能开启
						#	try:
						#		status = db.AutoStatus(id)
						#		if status == 0:
						#			switch_status = 0
						#			break
						#	except Exception as e:
						#		logger.info(e)


						#auto_status=1 自愈没有处于维护状态
						auto_status = db.McStatus(alarm)
						alert_type, alert_type_link = db.SendAlert(alarm)
						user = db.SendUser()

						#自愈功能关闭,直接发送告警
						if not auto_status:
							inner_iplist = []
							for p in ip_list:
								asset = db.Asset(p)
								logger.info(asset)
								inner_iplist.append(asset["ip"])

							inner_ip = ','.join(inner_iplist)


							msg = 'IP:%s, 告警项目: %s,自愈项: %s, 告警状态: %s, 告警次数: %s,请手动处理'%(inner_ip, alarm, alertpj, status, alertime)
							ACCESS_LIST = []
							ERROR_LIST = [msg]
							if alert_type == 1:
								SendMessages(alert_type_link,ACCESS_LIST,ERROR_LIST,user,comments='')
							elif alert_type == 2:
								atl = alert_type_link.split('|')[0]
								keyword = '关键词:' + alert_type_link.split('|')[1] + ', '
								msg = keyword + msg
								logger.info(msg)
								SendMs(atl, msg)

							else:
								pass

							# 次数加1
							fixtime += 1
							alert['fixtime'] = fixtime
							rc.hset(alarm, alertpj, json.dumps(alert))

						#开启自愈
						#if switch_status and auto_status:
						if auto_status:

							# 发送告警
							#try:
							if 1 == 1:
								MSG = {'alert_type':alert_type,'alert_type_link':alert_type_link,'user':user,'alarm':alarm}

								#判断自愈是否在沉默状态和沉默区间
								silence = db.AlertSilence()
								if silence[0] == 'on':
									nowtime = datetime.datetime.now()
									stime = datetime.datetime.now().strftime("%Y-%m-%d ") + silence[1]
									to_stime = datetime.datetime.strptime(stime, '%Y-%m-%d %H:%M:%S')
									etime = datetime.datetime.now().strftime("%Y-%m-%d ") + silence[2]
									to_etime = datetime.datetime.strptime(etime, '%Y-%m-%d %H:%M:%S')
									if to_stime <= nowtime <= to_etime:
										# 告警信息记录
										silence_msg = 'test:IP:%s, 告警项目: %s,自愈项: %s, 告警状态: %s, 告警次数: %s 处于自愈沉默区间,不触发自愈动作' % (
										ip, alarm, alertpj, status, alertime)
										logger.info(silence_msg)
										# 次数加1
										fixtime += 1
										alert['fixtime'] = fixtime
										rc.hset(alarm, alertpj, json.dumps(alert))
										continue
									else:
										# 沉默开关开启,但不在沉默区间触发自愈动作
										RemoteDispatch.delay(ip_list, item_list, MSG)
										# 告警信息记录
										selfhealingmes = 'IP:%s, 告警项目: %s,自愈项: %s, 告警状态: %s, 告警次数: %s,自愈次数: %s 小于等于最大设定值 %s,沉默开关开启,但不在沉默区间,触发自愈动作' % (
											ip, alarm, alertpj, status, alertime, fixtime, maxfixtime)
										logger.info(selfhealingmes)

										# 次数加1
										fixtime += 1
										alert['fixtime'] = fixtime
										rc.hset(alarm, alertpj, json.dumps(alert))

								else:
									#沉默开关关闭,直接触发自愈动作
									RemoteDispatch.delay(ip_list,item_list,MSG)
									# 告警信息记录
									selfhealingmes = 'IP:%s, 告警项目: %s,自愈项: %s, 告警状态: %s, 告警次数: %s,自愈次数: %s 小于等于最大设定值 %s, 沉默开关关闭,直接触发自愈动作' % (
									ip, alarm, alertpj, status, alertime, fixtime, maxfixtime)
									logger.info(selfhealingmes)

									# 次数加1
									fixtime += 1
									alert['fixtime'] = fixtime
									rc.hset(alarm, alertpj, json.dumps(alert))



						else:
							# 告警信息记录
							selfhealingmes = 'IP:%s, 告警项目: %s,自愈项: %s, 自愈状态: %s 禁止触发自愈动作,跳过！！！' % (
							ip, alarm, alertpj, str(auto_status))
							logger.info(selfhealingmes)

					else:
						selfhealingmes = 'IP:%s, 告警项目: %s,自愈项: %s, 告警状态: %s, 告警次数: %s,自愈次数: %s 大于设定值 %s 不做处理'%(ip,alarm,alertpj,status,alertime,fixtime,maxfixtime)
						logger.info(selfhealingmes)
						fixtime += 1
						alert['fixtime']= fixtime
						rc.hset(alarm,alertpj,json.dumps(alert))

				else:
					rc.hset(alarm,alertpj,json.dumps(alert))
					#告警信息记录
					alertmsg = '本次告警信息是 IP:%s, 告警项目: %s,自愈项: %s, 告警状态: %s, 告警次数: %s'%(ip,alarm,alertpj,status,alertime)
					logger.info(alertmsg)

			else:
				alertime = 1
				fixtime = 0
				status = 'BAD'
				alert = json.dumps({"alertime":alertime,"fixtime":fixtime,"status":status})
				rc.hset(alarm,alertpj,alert)

				#告警信息记录
				alertmsg = '首次创建告警信息是 IP:%s, 告警项目: %s,自愈项: %s, 告警状态: %s, 告警次数: %s'%(ip,alarm,alertpj,status,alertime)
				logger.info(alertmsg)